#include <sys/socket.h>
#include <netinet/in.h>

#include <err.h>
#include <stdlib.h>
#include <unistd.h>

#define LST_PORT 9001
#define BCK_LOG 10

extern void usage(int e);
extern void version(void);
extern int socket_bind_listen(sa_family_t family, in_port_t port,
	int backlog, int v6only);
extern void loop_accept(int socket);

int
main(int argc, char *const argv[])
{
	int ch;
	int inet_v4, inet_v6, v6only;
	int fd;
	sa_family_t family;
	in_port_t listen_port;

	inet_v4 = 0;
	inet_v6 = 0;
	while ((ch = getopt(argc, argv, "46hv")) != -1) {
		switch (ch) {
		case '4':
			inet_v4 = 1;
			break;
		case '6':
			inet_v6 = 1;
			break;
		case 'h':
			usage(EXIT_SUCCESS);
			break;
		case 'v':
			version();
			exit(EXIT_SUCCESS);
			break;
		case '?':
		default:
			usage(EXIT_FAILURE);
			break;
		}
	}

	argc -= optind;
	argv += optind;

	if (argc > 1)
		usage(EXIT_FAILURE);
	else if (argc == 1)
		listen_port = (in_port_t)atoi(*argv);
	else {
		listen_port = LST_PORT;
		warnx("listen on default port %d", listen_port);
	}

	if (!inet_v4 && !inet_v6)
		inet_v4 = inet_v6 = 1;

	if (inet_v4) {
		if (inet_v6) {
			family = AF_INET6;
			v6only = 0;
		} else
			family = AF_INET;
	} else if (inet_v6) {
		family = AF_INET6;
		v6only = 1;
	}

	if ((fd = socket_bind_listen(family, listen_port, BCK_LOG,
				v6only)) == -1)
		err(EXIT_FAILURE, "socket_bind_listen");

	loop_accept(fd);

	close(fd);
	return 0;
}
